package io.gitee.kotle.android

import com.android.tools.idea.wizard.template.*


sealed class BaseTemplate(
    val name: String,
    val classTypeName: String,
    val isNeedViewModel: Boolean,
    val isNeedViewModelDefault: Boolean,
) {
    object HolderTemplate : BaseTemplate("CompatBindingHolder", "Holder", false, false)
    object FragmentTemplate : BaseTemplate("CompatBindingFragment", "Fragment", true, true)
    object DialogTemplate : BaseTemplate("CompatBindingDialog", "DialogFragment", true, false)
}

fun createTemplate(temp: BaseTemplate) = template {
    name = temp.name
    description = "创建一个带有ViewBinding的${temp.classTypeName}"
    category = Category.Other
    formFactor = FormFactor.Mobile
    constraints = listOf(TemplateConstraint.Kotlin)
    screens = listOf(
        WizardUiContext.ActivityGallery,
        WizardUiContext.MenuEntry,
        WizardUiContext.NewProject,
        WizardUiContext.NewModule
    )

    val classPath = stringParameter {
        name = "${temp.classTypeName}类路径"
        constraints = listOf(Constraint.PACKAGE)
        default = "compat.app"
        help = "${temp.classTypeName}类的存放路径"
    }

    val className = stringParameter {
        name = "输入类名"
        constraints = listOf(Constraint.UNIQUE, Constraint.NONEMPTY)
        default = ""
        help = "输入类名,不需要输入${temp.classTypeName}"
    }

    val layoutName = stringParameter {
        name = "Layout布局文件"
        default = "layout_"
        constraints = listOf(Constraint.LAYOUT, Constraint.NONEMPTY)
        suggest = {
            temp.classTypeName.toLowerCase() + createLayoutName(className.value)
        }
    }

    val isNeedViewModel = booleanParameter {
        name = "是否创建ViewModel"
        default = temp.isNeedViewModelDefault
        help = "创建ViewModel"
        visible = {
            temp.isNeedViewModel
        }
    }

    widgets(
        PackageNameWidget(classPath),
        TextFieldWidget(className),
        CheckBoxWidget(isNeedViewModel),
        TextFieldWidget(layoutName),
        LanguageWidget(),
    )

    recipe = { data: TemplateData ->
        templateRecipe(
            temp,
            data as ModuleTemplateData,
            classPath.value,
            className.value,
            layoutName.value,
            isNeedViewModel.value
        )
    }
}

private fun RecipeExecutor.templateRecipe(
    temp: BaseTemplate,
    moduleTemplateData: ModuleTemplateData,
    classPath: String,
    className: String,
    layoutName: String,
    isNeedViewModel: Boolean,
) {
    val (projectData, srcOut, resOut) = moduleTemplateData
    val ktOrJavaExt = projectData.language.extension
    val packageName = projectData.applicationPackage ?: classPath
    val classNameWithExt = "${className}${temp.classTypeName}.${ktOrJavaExt}"
    val bindingName = getBindingName(layoutName)
    val classStr = when (temp) {
        BaseTemplate.FragmentTemplate -> {
            getFragmentStr(temp, packageName, classPath, className, bindingName, isNeedViewModel)
        }
        BaseTemplate.HolderTemplate -> {
            getHolderStr(temp, packageName, classPath, className, bindingName)
        }
        BaseTemplate.DialogTemplate -> {
            getDialogStr(temp, packageName, classPath, className, bindingName, isNeedViewModel)
        }
    }
    //class
    save(classStr, srcOut.resolve(classNameWithExt))
    //viewModel
    if (isNeedViewModel) {
        save(
            getViewModelStr(classPath, className),
            srcOut.resolve("${className}ViewModel.${ktOrJavaExt}")
        )
    }
    //layout
    saveLayout(classPath, "${className}${temp.classTypeName}", resOut, layoutName)
}

